package com.christina.engine.execution.model;

import com.christina.engine.processing.model.ProcessingContext;
import lombok.Getter;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 执行请求数据模型
 * 包含服务执行所需的所有信息
 */
@Getter
public class ExecutionRequest {
    
    private final String requestId;
    private final String serviceType;
    private final Map<String, Object> parameters;
    private final ProcessingContext context;
    private final LocalDateTime requestTime;
    private final Map<String, Object> metadata;
    
    private ExecutionRequest(Builder builder) {
        this.requestId = builder.requestId;
        this.serviceType = builder.serviceType;
        this.parameters = new HashMap<>(builder.parameters);
        this.context = builder.context;
        this.requestTime = builder.requestTime != null ? builder.requestTime : LocalDateTime.now();
        this.metadata = new HashMap<>(builder.metadata);
    }
    
    // 自定义getter方法返回防御性拷贝
    public Map<String, Object> getParameters() { 
        return new HashMap<>(parameters); 
    }
    
    public Map<String, Object> getMetadata() { 
        return new HashMap<>(metadata); 
    }
    
    // 便利方法
    public <T> T getParameter(String key, Class<T> type) {
        Object value = parameters.get(key);
        if (value != null && type.isInstance(value)) {
            return type.cast(value);
        }
        return null;
    }
    
    public boolean hasParameter(String key) {
        return parameters.containsKey(key);
    }
    
    public <T> T getMetadata(String key, Class<T> type) {
        Object value = metadata.get(key);
        if (value != null && type.isInstance(value)) {
            return type.cast(value);
        }
        return null;
    }
    
    public boolean hasMetadata(String key) {
        return metadata.containsKey(key);
    }
    
    // 可变方法（用于动态添加参数）
    public void addParameter(String key, Object value) {
        this.parameters.put(key, value);
    }
    
    // Builder模式
    public static class Builder {
        private String requestId;
        private String serviceType;
        private Map<String, Object> parameters = new HashMap<>();
        private ProcessingContext context;
        private LocalDateTime requestTime;
        private Map<String, Object> metadata = new HashMap<>();
        
        public Builder requestId(String requestId) {
            this.requestId = requestId;
            return this;
        }
        
        public Builder serviceType(String serviceType) {
            this.serviceType = serviceType;
            return this;
        }
        
        public Builder parameter(String key, Object value) {
            this.parameters.put(key, value);
            return this;
        }
        
        public Builder parameters(Map<String, Object> parameters) {
            this.parameters.putAll(parameters);
            return this;
        }
        
        public Builder context(ProcessingContext context) {
            this.context = context;
            return this;
        }
        
        public Builder requestTime(LocalDateTime requestTime) {
            this.requestTime = requestTime;
            return this;
        }
        
        public Builder metadata(String key, Object value) {
            this.metadata.put(key, value);
            return this;
        }
        
        public Builder metadata(Map<String, Object> metadata) {
            this.metadata.putAll(metadata);
            return this;
        }
        
        public ExecutionRequest build() {
            if (requestId == null || requestId.trim().isEmpty()) {
                throw new IllegalArgumentException("Request ID cannot be null or empty");
            }
            if (serviceType == null || serviceType.trim().isEmpty()) {
                throw new IllegalArgumentException("Service type cannot be null or empty");
            }
            if (context == null) {
                throw new IllegalArgumentException("Processing context cannot be null");
            }
            
            return new ExecutionRequest(this);
        }
    }
    
    public static Builder builder() {
        return new Builder();
    }
    
    // 静态工厂方法
    public static ExecutionRequest create(String serviceType, ProcessingContext context) {
        return builder()
                .requestId(java.util.UUID.randomUUID().toString())
                .serviceType(serviceType)
                .context(context)
                .build();
    }
    
    public static ExecutionRequest create(String serviceType, Map<String, Object> parameters, ProcessingContext context) {
        return builder()
                .requestId(java.util.UUID.randomUUID().toString())
                .serviceType(serviceType)
                .parameters(parameters)
                .context(context)
                .build();
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ExecutionRequest that = (ExecutionRequest) o;
        return Objects.equals(requestId, that.requestId);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(requestId);
    }
    
    @Override
    public String toString() {
        return "ExecutionRequest{" +
                "requestId='" + requestId + '\'' +
                ", serviceType='" + serviceType + '\'' +
                ", parametersCount=" + parameters.size() +
                ", requestTime=" + requestTime +
                ", metadataCount=" + metadata.size() +
                '}';
    }
}